import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:image/image.dart' as img;
import '../models/map_models.dart';
import 'tmx_parser.dart';

// 图片信息类
class ImageFileInfo {
  final String path;
  final String name;
  final int width;
  final int height;
  final String format;

  ImageFileInfo({
    required this.path,
    required this.name,
    required this.width,
    required this.height,
    required this.format,
  });
}

// 图块集建议类
class TileSetSuggestion {
  final String name;
  final String imagePath;
  final int tileWidth;
  final int tileHeight;
  final int columns;
  final int rows;
  final int tileCount;
  final int imageWidth;
  final int imageHeight;
  final String imageFormat;

  TileSetSuggestion({
    required this.name,
    required this.imagePath,
    required this.tileWidth,
    required this.tileHeight,
    required this.columns,
    required this.rows,
    required this.tileCount,
    required this.imageWidth,
    required this.imageHeight,
    required this.imageFormat,
  });
}

class FileService {
  static const String mapFileExtension = '.tmx';
  static const String defaultMapDir = 'MapEditor';
  
  // 请求存储权限
  static Future<bool> requestStoragePermission() async {
    final permission = Permission.storage;
    final status = await permission.request();
    return status.isGranted;
  }

  // 获取默认地图目录
  static Future<String> getDefaultMapDirectory() async {
    try {
      Directory? directory;
      if (Platform.isAndroid) {
        directory = await getExternalStorageDirectory();
      } else {
        directory = await getApplicationDocumentsDirectory();
      }
      
      if (directory == null) {
        throw Exception('无法获取存储目录');
      }
      
      final mapDir = Directory('${directory.path}/$defaultMapDir');
      if (!await mapDir.exists()) {
        await mapDir.create(recursive: true);
      }
      
      return mapDir.path;
    } catch (e) {
      throw Exception('创建地图目录失败: $e');
    }
  }

  // 打开TMX地图文件
  static Future<TileMap?> openMapFile() async {
    try {
      // 请求权限
      final hasPermission = await requestStoragePermission();
      if (!hasPermission) {
        throw Exception('需要存储权限才能打开文件');
      }

      final result = await FilePicker.platform.pickFiles(
        type: FileType.custom,
        allowedExtensions: ['tmx', 'TMX'],
        dialogTitle: '打开TMX地图文件',
      );

      if (result != null && result.files.isNotEmpty) {
        final file = result.files.first;
        if (file.path != null) {
          return await TMXParser.parseFromFile(file.path!);
        }
      }
      return null;
    } catch (e) {
      throw Exception('打开文件失败: $e');
    }
  }

  // 保存地图文件
  static Future<void> saveMapFile(TileMap map, String filePath) async {
    try {
      final hasPermission = await requestStoragePermission();
      if (!hasPermission) {
        throw Exception('需要存储权限才能保存文件');
      }

      await TMXParser.saveToFile(map, filePath);
    } catch (e) {
      throw Exception('保存文件失败: $e');
    }
  }

  // 另存为地图文件
  static Future<String?> saveAsMapFile(TileMap map, String suggestedName) async {
    try {
      final hasPermission = await requestStoragePermission();
      if (!hasPermission) {
        throw Exception('需要存储权限才能保存文件');
      }

      final defaultDir = await getDefaultMapDirectory();
      String fileName = suggestedName;
      if (!fileName.endsWith(mapFileExtension)) {
        fileName += mapFileExtension;
      }
      
      final filePath = '$defaultDir/$fileName';
      await TMXParser.saveToFile(map, filePath);
      return filePath;
    } catch (e) {
      throw Exception('另存为失败: $e');
    }
  }

  // 导出为文本格式
  static Future<void> exportAsText(TileMap map, String filePath) async {
    try {
      final hasPermission = await requestStoragePermission();
      if (!hasPermission) {
        throw Exception('需要存储权限才能导出文件');
      }

      final buffer = StringBuffer();
      buffer.writeln('地图编辑器导出文本');
      buffer.writeln('================');
      buffer.writeln('地图尺寸: ${map.width} x ${map.height}');
      buffer.writeln('图块尺寸: ${map.tileWidth} x ${map.tileHeight}');
      buffer.writeln('图层数量: ${map.layers.length}');
      buffer.writeln('');

      for (int layerIndex = 0; layerIndex < map.layers.length; layerIndex++) {
        final layer = map.layers[layerIndex];
        buffer.writeln('图层 ${layerIndex + 1}: ${layer.name}');
        buffer.writeln('可见性: ${layer.visible ? "是" : "否"}');
        buffer.writeln('透明度: ${(layer.opacity * 100).toInt()}%');
        buffer.writeln('');
        
        // 输出地图数据
        for (int y = 0; y < layer.height; y++) {
          for (int x = 0; x < layer.width; x++) {
            buffer.write('${layer.data[y][x].toString().padLeft(3)} ');
          }
          buffer.writeln();
        }
        buffer.writeln('');
      }

      final file = File(filePath);
      await file.writeAsString(buffer.toString());
    } catch (e) {
      throw Exception('导出文本失败: $e');
    }
  }

  // 导出为数组格式（用于代码）
  static Future<void> exportAsArray(TileMap map, String filePath) async {
    try {
      final hasPermission = await requestStoragePermission();
      if (!hasPermission) {
        throw Exception('需要存储权限才能导出文件');
      }

      final buffer = StringBuffer();
      buffer.writeln('// 地图编辑器导出的数组数据');
      buffer.writeln('// 地图尺寸: ${map.width} x ${map.height}');
      buffer.writeln('// 图块尺寸: ${map.tileWidth} x ${map.tileHeight}');
      buffer.writeln();

      for (int layerIndex = 0; layerIndex < map.layers.length; layerIndex++) {
        final layer = map.layers[layerIndex];
        final layerName = _sanitizeVariableName(layer.name);
        
        buffer.writeln('// 图层: ${layer.name}');
        buffer.writeln('const int ${layerName}Width = ${layer.width};');
        buffer.writeln('const int ${layerName}Height = ${layer.height};');
        buffer.writeln('const int ${layerName}Data[${layer.height}][${layer.width}] = {');
        
        for (int y = 0; y < layer.height; y++) {
          buffer.write('  {');
          for (int x = 0; x < layer.width; x++) {
            buffer.write(layer.data[y][x]);
            if (x < layer.width - 1) buffer.write(', ');
          }
          buffer.write('}');
          if (y < layer.height - 1) buffer.write(',');
          buffer.writeln();
        }
        buffer.writeln('};');
        buffer.writeln();
      }

      final file = File(filePath);
      await file.writeAsString(buffer.toString());
    } catch (e) {
      throw Exception('导出数组失败: $e');
    }
  }

  // 获取最近使用的文件列表
  static Future<List<String>> getRecentFiles() async {
    try {
      final defaultDir = await getDefaultMapDirectory();
      final directory = Directory(defaultDir);
      
      if (!await directory.exists()) {
        return [];
      }

      final files = await directory
          .list()
          .where((entity) => 
              entity is File && 
              entity.path.toLowerCase().endsWith(mapFileExtension))
          .cast<File>()
          .toList();

      // 按修改时间排序
      files.sort((a, b) => b.lastModifiedSync().compareTo(a.lastModifiedSync()));
      
      return files.take(10).map((file) => file.path).toList();
    } catch (e) {
      return [];
    }
  }

  // 检查文件是否存在
  static Future<bool> fileExists(String filePath) async {
    final file = File(filePath);
    return await file.exists();
  }

  // 获取文件名（不包含路径）
  static String getFileName(String filePath) {
    return filePath.split(Platform.pathSeparator).last;
  }

  // 获取不带扩展名的文件名
  static String getFileNameWithoutExtension(String filePath) {
    final fileName = getFileName(filePath);
    final dotIndex = fileName.lastIndexOf('.');
    if (dotIndex != -1) {
      return fileName.substring(0, dotIndex);
    }
    return fileName;
  }

  // 生成安全的变量名
  static String _sanitizeVariableName(String name) {
    return name
        .replaceAll(RegExp(r'[^a-zA-Z0-9_]'), '_')
        .replaceAll(RegExp(r'^[^a-zA-Z_]'), '_')
        .toLowerCase();
  }

  // 选择图片文件并分析
  static Future<ImageFileInfo?> pickImageFile() async {
    try {
      final result = await FilePicker.platform.pickFiles(
        type: FileType.image,
        dialogTitle: '选择图片文件',
        allowMultiple: false,
      );

      if (result != null && result.files.isNotEmpty) {
        final file = result.files.first;
        if (file.path != null) {
          return await analyzeImageFile(file.path!);
        }
      }
      return null;
    } catch (e) {
      throw Exception('选择图片失败: $e');
    }
  }

  // 分析图片文件，获取图片信息
  static Future<ImageFileInfo> analyzeImageFile(String imagePath) async {
    try {
      final imageFile = File(imagePath);
      if (!await imageFile.exists()) {
        throw Exception('图片文件不存在');
      }

      // 使用image包来解析图片
      final imageBytes = await imageFile.readAsBytes();
      final image = img.decodeImage(imageBytes);
      
      if (image == null) {
        throw Exception('无法解析图片文件');
      }

      final fileName = getFileNameWithoutExtension(imagePath);
      
      return ImageFileInfo(
        path: imagePath,
        name: fileName,
        width: image.width,
        height: image.height,
        format: _getImageFormat(imagePath),
      );
    } catch (e) {
      throw Exception('分析图片失败: $e');
    }
  }

  // 获取图片格式
  static String _getImageFormat(String path) {
    final extension = path.toLowerCase().split('.').last;
    switch (extension) {
      case 'png':
        return 'PNG';
      case 'jpg':
      case 'jpeg':
        return 'JPEG';
      case 'gif':
        return 'GIF';
      case 'bmp':
        return 'BMP';
      default:
        return extension.toUpperCase();
    }
  }

  // 创建图块集建议
  static TileSetSuggestion suggestTileSetFromImage(ImageFileInfo imageInfo, int tileWidth, int tileHeight) {
    final columns = (imageInfo.width / tileWidth).floor();
    final rows = (imageInfo.height / tileHeight).floor();
    final tileCount = columns * rows;
    
    return TileSetSuggestion(
      name: imageInfo.name,
      imagePath: imageInfo.path,
      tileWidth: tileWidth,
      tileHeight: tileHeight,
      columns: columns,
      rows: rows,
      tileCount: tileCount,
      imageWidth: imageInfo.width,
      imageHeight: imageInfo.height,
      imageFormat: imageInfo.format,
    );
  }

  // 创建示例地图文件
  static Future<String> createSampleMap() async {
    final defaultDir = await getDefaultMapDirectory();
    final samplePath = '$defaultDir/sample.tmx';
    
    final sampleMap = TileMap.createNew(
      width: 20,
      height: 15,
      tileWidth: 32,
      tileHeight: 32,
    );
    
    // 添加一些示例数据
    final layer = sampleMap.layers.first;
    for (int y = 0; y < 5; y++) {
      for (int x = 0; x < 5; x++) {
        layer.data[y][x] = (x + y) % 5 + 1;
      }
    }
    
    await TMXParser.saveToFile(sampleMap, samplePath);
    return samplePath;
  }
}